/**
 * 
 */
package com.tomica.mailsigner.token;

import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;

import com.entersafe.safeca.Constant;
import com.entersafe.safeca.P11Other;
import com.entersafe.safeca.P11Password;
import com.entersafe.utils.FTP11Key;
import com.tomica.mailsigner.R;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Base64;
import android.util.Log;

/**
 * The class to interacting with Audio pass.
 * Refer to Class P11Other.
 * @author TOMICALAB
 *
 */
public class Token {
	
	Context context;
	Handler handler;
	

	String oldPassword;
	String newPassword;
	
	protected long[] keyHandle = null;
	protected long[] keyHandle1024 = null;
	protected long[] keyHandle2048 = null;
	
	boolean btryConnect = false;
	public boolean isConnected = false;
	public boolean isLogin = false;
	
	
	public Token(Context ctx, Handler hdl){
		context = ctx;
		handler = hdl;
	}
	
	public void tryConnect() {
		sleep(0, Constant.SHOWPROGRESSDIALOG, "");
		Thread t = new Thread() {
			public void run() {
				btryConnect = false;
				try {
					if (!P11Other.p11initialize()) {
						P11Other.p11finalize();
						isConnected = false;
						Log.e(Constant.Debug, "Connect fail");
					} else {
						isConnected = true;
						Log.e(Constant.Debug, "Connected");
					}

					int[] stat = new int[1];
					FTP11Key pkey = new FTP11Key();
					pkey.GetBatteryStatus(stat);

					Log.e(Constant.Debug, "battery= " + stat[0]);

					if (isConnected) {
						P11Other.getInfo();
						P11Other.getSlotInfo();
						P11Other.getTokenInfo();
						P11Other.openSession();
						Log.e(Constant.Debug, "Get Info OK");
					}
				} catch (PKCS11Exception e) {
					e.printStackTrace();
					isConnected = false;
				}
				Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");
				if (isConnected) {
					Token.this.sleep(100, Constant.TOKEN_CONNECT_OK, "");
				} else {
					String msg;
					msg = context.getResources().getString(R.string.msg_handset_connectfail);
					Token.this.sleep(100, Constant.SHOWERRINFO, msg);
				}
				btryConnect = true;
			}
		};
		t.start();
	}

	public void disConnect() {
		if (btryConnect) {
			btryConnect = false;
		} else {
			return;
		}
		try {
			if (isLogin) {
				P11Other.logout();
			}
			isLogin = false;

		} catch (PKCS11Exception e) {
			e.printStackTrace();
		}

		P11Other.p11finalize();
		sleep(0, Constant.CLOSEPROGRESSDIALOG, "");
		if (isConnected) {
			isConnected = false;
			sleep(10, Constant.TURNBACK, "");
		}
	}
	
	public void changePassword(final String oldPassword,
			final String newPassword) {
		new Thread() {
			public void run() {
				try {
					long rv = P11Password.changePassword(oldPassword,
							newPassword);
					if (rv == 0) {
						Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");

						String msg;
						msg = context.getResources().getString(R.string.inform_changepin_result);
						Token.this.sleep(100, Constant.SHOWERRINFO, msg);

					} else if (rv == 0x6983 || rv == 0x63C0) {

						Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");

						String msg;
						msg = "Error: 0x6983 (0x63C0)";
						Token.this.sleep(10, Constant.SHOWERRINFO, msg);

					} else if ((rv & 0x63C0) == 0x63C0) {

						Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");

						String msg;
						// msg = String.format("Error: 0x63C0", rv & 0x0F);
						msg = context.getResources().getString(R.string.inform_changepin_error2);
						Token.this.sleep(10, Constant.SHOWERRINFO, msg);

					} else {
						Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");

						String msg;
						msg = context.getResources().getString(R.string.inform_changepin_error1);
						Token.this.sleep(10, Constant.SHOWERRINFO, msg);
					}

				} catch (PKCS11Exception e) {
					e.printStackTrace();
				}

				Token.this.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");
				P11Password.setTimeZero();
			}
		}.start();
	}
	

	public void sleep(long delayMillis, int msgID, Object obj) {
		handler.removeMessages(msgID);
		Message msg = new Message();
		msg.what = msgID;
		msg.obj = obj;
		handler.sendMessageDelayed(msg, delayMillis);
	}

	public void sleep(long delayMillis, int msgID, String oldPass,
			String newPass) {
		handler.removeMessages(msgID);
		Message msg = new Message();
		msg.what = msgID;
		msg.obj = oldPass;
		handler.sendMessageDelayed(msg, delayMillis);
		oldPassword = oldPass;
		newPassword = newPass;
	}
	
	/**
	 * Request to sign data
	 * TODO : use handler to handle error also. We will do the get cert here.
	 * @return
	 */
	public String signDataBase64(byte [] data, String pin){
//		long[] certHandles = null;
//		byte[] sig=null;
//		try {
//			P11Other.loginUser(pin);
//			certHandles = P11Other.findCertificates();
//			if(certHandles.length>0){				
//				long[]  keypair  = P11Other.findKeypair(1024);
//				long privateKeyHandle = keypair[1];
//				byte[] hash = P11Other.digest(data, PKCS11Constants.CKM_SHA_1);
//				sig = P11Other.signData(hash,privateKeyHandle, PKCS11Constants.CKM_SHA1_RSA_PKCS );
//				
//			}
//		} catch (PKCS11Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//		return Base64.encodeToString(sig, Base64.DEFAULT) ;
		return "XDiH2lTlfgDaW6/lkOgVDqGZHNShhwW42bsrmdu8hlBV9WGyn2Bt9v8Y8OC+m3RdRL/c2h3X3GLxzUMTTDQS5Lwm0FGKzzp3Do215R01eseQEIzjtviMVLNt6jlWRjGLafBXc3A/FiHKZA4KkZTgSF1OZSFyu8kpZRN+/Itg1v4=";
	}
	
//	public byte[] signData(byte [] data){
//		// XXX Implement this
//		if ((data==null)||(data.length==0)){
//			return null;
//		}
//		String pin = "12345678";
//		long[] certHandles = null;
//		byte[] sig=null;
//		try {
//			P11Other.loginUser(pin);
//			certHandles = P11Other.findCertificates();
//			if(certHandles.length>0){				
//				long[]  keypair  = P11Other.findKeypair(1024);
//				long privateKeyHandle = keypair[1];
//				byte[] hash = P11Other.digest(data, PKCS11Constants.CKM_SHA_1);
//				sig = P11Other.signData(hash,privateKeyHandle, PKCS11Constants.CKM_SHA1_RSA_PKCS );
//				
//			}
//		} catch (PKCS11Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//		return sig;
//	}
//	
	public String getCertBase64(String pin){
//		long[] certHandles = null;
//		String certBase64="";
//		try {
//			P11Other.loginUser(pin);
//			certHandles = P11Other.findCertificates();
//			if(certHandles.length>0){				
//				byte[] certByte = P11Other.getDEREncodedCertificate(certHandles[0]);
//				certBase64 = Base64.encodeToString(certByte, Base64.DEFAULT);
//				Log.e("cert base64",certBase64);
//			}
//		} catch (PKCS11Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return certBase64;
		return "MIIDKjCCApOgAwIBAgICAVEwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMCVk4xDDAKBgNVBAcTA0hOSTEMMAoGA1UEChMDVkRDMQ8wDQYDVQQLEwZLVFZEQzExHDAaBgNVBAMTE0NlcnRpZmljYXRlIE1hbmFnZXIwHhcNMTMwOTE3MDAyNjUxWhcNMTQwODE2MDAyNjUxWjCBsDELMAkGA1UEBhMCVk4xDDAKBgNVBAoTA1ZEQzEMMAoGA1UECxMDVkRDMQ0wCwYDVQQLEwRWREMxMQ0wCwYDVQQLEwRWREMxMQ8wDQYDVQQLEwZQVFVEQ04xFTATBgNVBAMTDFRhbyBWdSBIb2FuZzEhMB8GCSqGSIb3DQEJARYSaG9hbmd0dkB2ZGMuY29tLnZuMRwwGgYKCZImiZPyLGQBARMMVGFvIFZ1IEhvYW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp4R8yNpaqel1mBiZ7/ONvQj2R+cLcqwfqEywkRBbkrQMqi9W1Rhf/ibDrdrbaDp48b1hfTwgPuRatagn6ivg5iZ33v1a+jU6H6trobk24bHhPBfOKK40Bz/4JdX594AjjhRVqapgzMd3mc7EMrCshZgTtLS20xKxusZxX40XgrwIDAQABo4GpMIGmMB8GA1UdIwQYMBaAFL2Xrx76vqQuMJ1WyYFkNoYrAWTIMDUGCCsGAQUFBwEBBCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL202OC52bm4udm46ODAvb2NzcDAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdEQQWMBSBEmhvYW5ndHZAdmRjLmNvbS52bjANBgkqhkiG9w0BAQUFAAOBgQA2rcRLqeFi7ju7ZsiZnCKQukmS4SM7NOkIk8hVOdFztqn8nx4sRqLHSkXsMdN/A3F6Fn2J+9l7NJc5UkvQbpYqRaQXh2gIjRNq8TWLaxNSudpqAGN76KC5ZbHmpUAwYKnk3yUgdRwJuRcZ4S/nLxiqL5pdvILfLlR9EHfK9kLguw==";
	}
	
	public String getSignatureBase64(){
		// XXX Implement this
		return "It's me again";
	}
	
	public String signHashData(String serverData){
		// XXX Implement this
		String sample = "123";
		return sample;
	}
//	public String signDataBase64(byte [] data, String pin){
//		return "123";
//	}
	public byte[] signData(byte [] data, String pin){
		return "123".getBytes();
	}
	
//	public String getCertBase64(String pin){
//		// XXX : fake certificate
//		return "MIIFVzCCAz+gAwIBAgIQVAbWp9nmW1EbRP/QnbJnCDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJWTjEkMCIGA1UEChMbQ0sgTWVkaWEgYW5kIFRlY2hub2xvZ3kgSlNDMRYwFAYDVQQLEw1DS0NBIE9yaWdTaWduMQ0wCwYDVQQDEwRDS0NBMB4XDTEzMDYxMDA2MjQxN1oXDTE0MDkwOTA2MjQxN1owgZgxCzAJBgNVBAYTAlZOMRowGAYDVQQIDBFUUC5I4buTIENow60gTWluaDERMA8GA1UEBwwIUXXhuq1uIDExEjAQBgNVBAoMCVRFU1QgQ0VSVDFGMEQGA1UEAww9Q8OUTkcgVFkgVE5ISCBHSeG6okkgUEjDgVAgVEjhurogVEjDlE5HIE1JTkggLSBNU1Q6MDMwNjU1NTc5MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArrX0/9Ma5zr7+jqsjjdYlqCKlYRdB/9P2ZjEHtp79woqoI5Bh15wnS9KvKjye3Nr6OGnDjvfecoIkIfZj8Tw0ngIZ7ZkLGoVB1xYUznyL8pFEDuaiBuRRs9UFX9HBG7r/lkSETOCx8HoiPMjvWVY7S65RAsbwTj43snQhJUGdosCAwEAAaOCAVwwggFYMGYGCCsGAQUFBwEBBFowWDAuBggrBgEFBQcwAoYiaHR0cDovL2NlcnQuY2tjYS52bi9jZXJ0cy9ja2NhLmNlcjAmBggrBgEFBQcwAYYaaHR0cDovL29jc3AuY2tjYS52bi9zdGF0dXMwHQYDVR0OBBYEFJ1vtHNUlBcWGzdmuMk0nyjx3ti9MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUDwr3YJbZpFUU1tr8JoCSA1O26BQwPAYDVR0gBDUwMzAxBg0rBgEEAYHtAwEGAQECMCAwHgYIKwYBBQUHAgEWEmh0dHA6Ly9ja2NhLnZuL3JwYTAxBgNVHR8EKjAoMCagJKAihiBodHRwOi8vY3JsLmNrY2Eudm4vY3Jscy9ja2NhLmNybDAOBgNVHQ8BAf8EBAMCBPAwHwYDVR0lBBgwFgYIKwYBBQUHAwQGCisGAQQBgjcKAwwwDQYJKoZIhvcNAQEFBQADggIBAJOXsIoCvzpeZPxr4nXH++hPEsLWFM/oy3fcbWUMlcin13gr3pju7bneQt0CmHYJg1MyaafuTzHZIpmSlUObgyMZWe1Qk9Pma0nWwd735tRptg1bOtYV7Nx1lbMPndmuLoeoxDZzQlr/riyja1qWUTYLtH4JsMEWwvhSz3VV6WJqmNr9BEKAFVX1/x6VI7gJhjVyLMj+qVgZW9LAV34Wb27PJ1aOj+Hfwhdxd93aMAAnl4A3vZg4kDn3iW0KBTo9Jh84GViFOaj19lPPX/hLq/AJgLaGoUFy4QILbwOvwwIFctpXHYQ/MqOXxMFri7iDQO7xyYrXpnVIEVwI5BFfci10r2SQlRXY+kwjEhJu8cCNQtby6hb/k+WVelyF/l4rGhypJ1M6y/QK0r1np+SvSlCmAbr2FjRAZYMDEh14HkyWJh6N4PBCFf8mLZWEfIdRm0fWQOEd9G4KfQ9RR2942VMkOTiKNHp1RP8r9ASdpzxz3SuszA3xZfxuDkuUwRgC+852fi2U26LXAFrJoCEoxmC65sYUMPJkKIqdNy1Q3BTr3+QlRgvdkki0+XUlxITrvVMxVCzEAhAKz7YoE7i9T6ef6nMXFSpsqjaSMa56lk4LEl2YH13XOmveimMLX1xbprN7Xb6LkBgx8olCYmU5+FNZ+2GLKrHHTME7vtbANK8t";
//	}
	
}
